home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / boot / czesc_2 / toolmanager / source / prefs / iconwindow.c < prev    next >
C/C++ Source or Header  |  1993-05-15  |  21KB  |  745 lines

  1. /*
  2.  * iconwindow.c  V2.1
  3.  *
  4.  * icon edit window handling
  5.  *
  6.  * (c) 1990-1993 Stefan Becker
  7.  */
  8.  
  9. #include "ToolManagerConf.h"
  10.  
  11. /* Icon node */
  12. struct IconNode {
  13.                  struct Node  in_Node;
  14.                  ULONG        in_Flags;
  15.                  char        *in_Exec;
  16.                  char        *in_Image;
  17.                  char        *in_Sound;
  18.                  LONG         in_XPos;
  19.                  LONG         in_YPos;
  20.                 };
  21.  
  22. /* Window data */
  23. static struct Gadget *gl;             /* Gadget list */
  24. static struct Window *w;              /* Window */
  25. static struct MsgPort *wp;            /* Window user port */
  26. static UWORD ww,wh;                   /* Window size */
  27. static struct IconNode *CurrentNode;
  28. static ULONG CurrentGadgetNum;
  29. static BOOL ReqOpen;
  30. static struct Requester DummyReq;
  31. #define WINDOW_IDCMP (IDCMP_CLOSEWINDOW|IDCMP_REFRESHWINDOW|BUTTONIDCMP|\
  32.                       CHECKBOXIDCMP|STRINGIDCMP|TEXTIDCMP|IDCMP_VANILLAKEY)
  33.  
  34. /* Gadget data */
  35. #define GAD_NAME_STR   0 /* Gadgets with labels */
  36. #define GAD_EXEC_BUT   1
  37. #define GAD_IMAGE_BUT  2
  38. #define GAD_SOUND_BUT  3
  39. #define GAD_XPOS_INT   4
  40. #define GAD_YPOS_INT   5
  41.  
  42. #define GAD_EXEC_TXT   6
  43. #define GAD_IMAGE_TXT  7
  44. #define GAD_SOUND_TXT  8
  45.  
  46. #define GAD_POSITION   9 /* Cycle gadget */
  47.  
  48. #define GAD_SHOWNAME  10 /* Checkbox gadget */
  49.  
  50. #define GAD_OK        11
  51. #define GAD_CANCEL    12
  52. #define GADGETS       13
  53. static struct GadgetData gdata[GADGETS];
  54.  
  55. /* Gadget tags */
  56. static struct TagItem nametags[]={GTST_String,   NULL,
  57.                                   GTST_MaxChars, SGBUFLEN,
  58.                                   TAG_DONE};
  59.  
  60. static struct TagItem exectags[]={GTTX_Text,   NULL,
  61.                                   GTTX_Border, TRUE,
  62.                                   TAG_DONE};
  63.  
  64. static struct TagItem imagetags[]={GTTX_Text,   NULL,
  65.                                    GTTX_Border, TRUE,
  66.                                    TAG_DONE};
  67.  
  68. static struct TagItem soundtags[]={GTTX_Text,   NULL,
  69.                                    GTTX_Border, TRUE,
  70.                                    TAG_DONE};
  71.  
  72. static char *cyclelabels[3]={NULL, NULL, NULL};
  73. static struct TagItem cycletags[]={GTCY_Labels, (ULONG) cyclelabels,
  74.                                    GTCY_Active, 0,
  75.                                    TAG_DONE};
  76.  
  77. static struct TagItem xpostags[]={GTIN_Number,   0,
  78.                                   GTIN_MaxChars, 10,
  79.                                   TAG_DONE};
  80.  
  81. static struct TagItem ypostags[]={GTIN_Number,   0,
  82.                                   GTIN_MaxChars, 10,
  83.                                   TAG_DONE};
  84.  
  85. static struct TagItem showntags[]={GTCB_Checked, FALSE,
  86.                                    GTCB_Scaled,  TRUE,
  87.                                    TAG_DONE};
  88.  
  89. /* Gadget vanilla key data */
  90. #define KEY_NAME   0
  91. #define KEY_EXEC   1
  92. #define KEY_IMAGE  2
  93. #define KEY_SOUND  3
  94. #define KEY_XPOS   4
  95. #define KEY_YPOS   5
  96. #define KEY_SHOW   6
  97. #define KEY_OK     7
  98. #define KEY_CANCEL 8
  99. static char KeyArray[KEY_CANCEL+1];
  100.  
  101. /* Init icon edit window */
  102. void InitIconEditWindow(UWORD left, UWORD fheight)
  103. {
  104.  ULONG labwidth,gadwidth,cycwidth,cbwidth,butwidth;
  105.  ULONG strheight=fheight+2;
  106.  ULONG i,tmp,yadd;
  107.  struct GadgetData *gd;
  108.  
  109.  /* Init strings */
  110.  gdata[GAD_NAME_STR].name  =AppStrings[MSG_WINDOW_NAME_GAD];
  111.  gdata[GAD_EXEC_BUT].name  =AppStrings[MSG_WINDOW_EXEC_GAD];
  112.  gdata[GAD_IMAGE_BUT].name =AppStrings[MSG_WINDOW_IMAGE_GAD];
  113.  gdata[GAD_SOUND_BUT].name =AppStrings[MSG_WINDOW_SOUND_GAD];
  114.  gdata[GAD_XPOS_INT].name  =AppStrings[MSG_WINDOW_LEFTEDGE_GAD];
  115.  gdata[GAD_YPOS_INT].name  =AppStrings[MSG_WINDOW_TOPEDGE_GAD];
  116.  cyclelabels[0]            =AppStrings[MSG_WINDOW_POSITION_OPEN_LABEL];
  117.  cyclelabels[1]            =AppStrings[MSG_WINDOW_POSITION_CLOSE_LABEL];
  118.  gdata[GAD_SHOWNAME].name  =AppStrings[MSG_ICONWIN_SHOWNAME_GAD];
  119.  gdata[GAD_OK].name        =AppStrings[MSG_WINDOW_OK_GAD];
  120.  gdata[GAD_CANCEL].name    =AppStrings[MSG_WINDOW_CANCEL_GAD];
  121.  
  122.  /* Calculate maximum label width for string gadgets */
  123.  labwidth=0;
  124.  gd=&gdata[GAD_NAME_STR];
  125.  for (i=GAD_NAME_STR; i<=GAD_YPOS_INT; i++, gd++)
  126.   if ((tmp=TextLength(&TmpRastPort,gd->name,strlen(gd->name))) > labwidth)
  127.    labwidth=tmp;
  128.  labwidth+=2*INTERWIDTH;
  129.  
  130.  /* Calculate minimum string gadget width */
  131.  gadwidth=TextLength(&TmpRastPort,AppStrings[MSG_ICONWIN_NEWNAME],
  132.                      strlen(AppStrings[MSG_ICONWIN_NEWNAME]))+2*INTERWIDTH;
  133.  
  134.  /* Calculate minimum window width */
  135.  ww=labwidth+gadwidth+2*INTERWIDTH;
  136.  
  137.  /* Calculate maximum cyclegadget width */
  138.  {
  139.   char **s;
  140.  
  141.   cycwidth=0;
  142.   s=cyclelabels;
  143.   for (i=0; i<=1; i++, s++)
  144.    if ((tmp=TextLength(&TmpRastPort,*s,strlen(*s))) > cycwidth)
  145.     cycwidth=tmp;
  146.   cycwidth+=5*INTERWIDTH;
  147.  }
  148.  if ((tmp=cycwidth+INTERWIDTH) > ww) ww=tmp;
  149.  
  150.  /* Calculate checkbox label width */
  151.  gd=&gdata[GAD_SHOWNAME];
  152.  cbwidth=TextLength(&TmpRastPort,gd->name,strlen(gd->name))+INTERWIDTH
  153.          +CHECKBOX_WIDTH;
  154.  if ((tmp=cbwidth+INTERWIDTH) > ww) ww=tmp;
  155.  
  156.  /* Calculate button gadgets width */
  157.  gd=&gdata[GAD_OK];
  158.  butwidth=TextLength(&TmpRastPort,gd->name,strlen(gd->name));
  159.  gd++;
  160.  if ((tmp=TextLength(&TmpRastPort,gd->name,strlen(gd->name))) > butwidth)
  161.   butwidth=tmp;
  162.  butwidth+=2*INTERWIDTH;
  163.  if ((tmp=2*(butwidth+INTERWIDTH)) > ww) ww=tmp;
  164.  
  165.  /* window height */
  166.  wh=9*fheight+9*INTERHEIGHT+12;
  167.  if (!OSV39) wh+=INTERHEIGHT;
  168.  
  169.  /* Init gadgets */
  170.  gd=gdata;
  171.  tmp=WindowTop+INTERHEIGHT;
  172.  gadwidth=ww-labwidth-2*INTERWIDTH; /* String gadget width */
  173.  i=labwidth;
  174.  labwidth+=left+INTERWIDTH;
  175.  yadd=strheight+INTERHEIGHT;
  176.  
  177.  /* Name string gadget */
  178.  gd->type=STRING_KIND;
  179.  gd->flags=PLACETEXT_LEFT;
  180.  gd->tags=nametags;
  181.  gd->left=labwidth;
  182.  gd->top=tmp;
  183.  gd->width=gadwidth;
  184.  gd->height=strheight;
  185.  tmp+=yadd;
  186.  
  187.  /* Exec object button gadget */
  188.  gd++;
  189.  gd->type=BUTTON_KIND;
  190.  gd->flags=PLACETEXT_IN;
  191.  gd->left=left;
  192.  gd->top=tmp;
  193.  gd->width=i;
  194.  gd->height=strheight;
  195.  tmp+=yadd;
  196.  
  197.  /* Image object button gadget */
  198.  gd++;
  199.  gd->type=BUTTON_KIND;
  200.  gd->flags=PLACETEXT_IN;
  201.  gd->left=left;
  202.  gd->top=tmp;
  203.  gd->width=i;
  204.  gd->height=strheight;
  205.  tmp+=yadd;
  206.  
  207.  /* Sound object button gadget */
  208.  gd++;
  209.  gd->name=AppStrings[MSG_WINDOW_SOUND_GAD];
  210.  gd->type=BUTTON_KIND;
  211.  gd->flags=PLACETEXT_IN;
  212.  gd->left=left;
  213.  gd->top=tmp;
  214.  gd->width=i;
  215.  gd->height=strheight;
  216.  tmp+=yadd+fheight+INTERHEIGHT;
  217.  
  218.  /* Leftedge integer gadget */
  219.  gd++;
  220.  gd->type=INTEGER_KIND;
  221.  gd->flags=PLACETEXT_LEFT;
  222.  gd->tags=xpostags;
  223.  gd->left=labwidth;
  224.  gd->top=tmp;
  225.  gd->width=gadwidth;
  226.  gd->height=strheight;
  227.  tmp+=yadd;
  228.  
  229.  /* TopEdge integer gadget */
  230.  gd++;
  231.  gd->type=INTEGER_KIND;
  232.  gd->flags=PLACETEXT_LEFT;
  233.  gd->tags=ypostags;
  234.  gd->left=labwidth;
  235.  gd->top=tmp;
  236.  gd->width=gadwidth;
  237.  gd->height=strheight;
  238.  
  239.  /* Exec object text gadget */
  240.  tmp=WindowTop+yadd+INTERHEIGHT;
  241.  gd++;
  242.  gd->type=TEXT_KIND;
  243.  gd->tags=exectags;
  244.  gd->left=labwidth;
  245.  gd->top=tmp;
  246.  gd->width=gadwidth;
  247.  gd->height=strheight;
  248.  tmp+=yadd;
  249.  
  250.  /* Image object text gadget */
  251.  gd++;
  252.  gd->type=TEXT_KIND;
  253.  gd->tags=imagetags;
  254.  gd->left=labwidth;
  255.  gd->top=tmp;
  256.  gd->width=gadwidth;
  257.  gd->height=strheight;
  258.  tmp+=yadd;
  259.  
  260.  /* Sound object text gadget */
  261.  gd++;
  262.  gd->type=TEXT_KIND;
  263.  gd->tags=soundtags;
  264.  gd->left=labwidth;
  265.  gd->top=tmp;
  266.  gd->width=gadwidth;
  267.  gd->height=strheight;
  268.  tmp+=yadd;
  269.  
  270.  /* Position cycle gadget */
  271.  gd++;
  272.  gd->type=CYCLE_KIND;
  273.  gd->flags=PLACETEXT_IN;
  274.  gd->tags=cycletags;
  275.  gd->left=left;
  276.  gd->top=tmp;
  277.  gd->width=ww-INTERWIDTH;
  278.  gd->height=fheight;
  279.  
  280.  /* Showname checkbox gadget */
  281.  tmp=WindowTop+7*fheight+8*INTERHEIGHT+12;
  282.  gd++;
  283.  gd->type=CHECKBOX_KIND;
  284.  gd->flags=PLACETEXT_RIGHT;
  285.  gd->tags=showntags;
  286.  gd->left=(ww-cbwidth-INTERWIDTH)/2+left;
  287.  gd->top=tmp;
  288.  gd->width=CHECKBOX_WIDTH;
  289.  gd->height=fheight-INTERHEIGHT;
  290.  tmp+=fheight;
  291.  if (!OSV39) tmp+=INTERHEIGHT;
  292.  
  293.  /* OK button gadget */
  294.  gd++;
  295.  gd->type=BUTTON_KIND;
  296.  gd->flags=PLACETEXT_IN;
  297.  gd->left=left;
  298.  gd->top=tmp;
  299.  gd->width=butwidth;
  300.  gd->height=fheight;
  301.  
  302.  /* Cancel button gadget */
  303.  gd++;
  304.  gd->type=BUTTON_KIND;
  305.  gd->flags=PLACETEXT_IN;
  306.  gd->left=ww-butwidth-INTERWIDTH+left;
  307.  gd->top=tmp;
  308.  gd->width=butwidth;
  309.  gd->height=fheight;
  310.  
  311.  /* Init vanilla key array */
  312.  KeyArray[KEY_NAME]  =FindVanillaKey(gdata[GAD_NAME_STR].name);
  313.  KeyArray[KEY_EXEC]  =FindVanillaKey(gdata[GAD_EXEC_BUT].name);
  314.  KeyArray[KEY_IMAGE] =FindVanillaKey(gdata[GAD_IMAGE_BUT].name);
  315.  KeyArray[KEY_SOUND] =FindVanillaKey(gdata[GAD_SOUND_BUT].name);
  316.  KeyArray[KEY_XPOS]  =FindVanillaKey(gdata[GAD_XPOS_INT].name);
  317.  KeyArray[KEY_YPOS]  =FindVanillaKey(gdata[GAD_YPOS_INT].name);
  318.  KeyArray[KEY_SHOW]  =FindVanillaKey(gdata[GAD_SHOWNAME].name);
  319.  KeyArray[KEY_OK]    =FindVanillaKey(gdata[GAD_OK].name);
  320.  KeyArray[KEY_CANCEL]=FindVanillaKey(gdata[GAD_CANCEL].name);
  321.  
  322.  /* Init dummy requester structure */
  323.  InitRequester(&DummyReq);
  324. }
  325.  
  326. /* Free icon node */
  327. void FreeIconNode(struct Node *node)
  328. {
  329.  struct IconNode *in=(struct IconNode *) node;
  330.  char *s;
  331.  
  332.  if (s=in->in_Node.ln_Name) free(s);
  333.  if (s=in->in_Exec) free(s);
  334.  if (s=in->in_Image) free(s);
  335.  if (s=in->in_Sound) free(s);
  336.  
  337.  /* Free node */
  338.  FreeMem(in,sizeof(struct IconNode));
  339. }
  340.  
  341. /* Copy image node */
  342. struct Node *CopyIconNode(struct Node *node)
  343. {
  344.  struct IconNode *in,*orignode=(struct IconNode *) node;
  345.  
  346.  /* Alloc memory for icon node */
  347.  if (in=AllocMem(sizeof(struct IconNode),MEMF_PUBLIC|MEMF_CLEAR)) {
  348.  
  349.   /* Got an old node? */
  350.   if (orignode) {
  351.    /* Yes, copy it */
  352.    if ((!orignode->in_Node.ln_Name || (in->in_Node.ln_Name=
  353.                                         strdup(orignode->in_Node.ln_Name))) &&
  354.        (!orignode->in_Exec || (in->in_Exec=strdup(orignode->in_Exec))) &&
  355.        (!orignode->in_Image || (in->in_Image=strdup(orignode->in_Image))) &&
  356.        (!orignode->in_Sound || (in->in_Sound=strdup(orignode->in_Sound)))) {
  357.     /* Copy flags & numbers */
  358.     in->in_Flags=orignode->in_Flags;
  359.     in->in_XPos=orignode->in_XPos;
  360.     in->in_YPos=orignode->in_YPos;
  361.     return(in);
  362.    }
  363.   } else
  364.    /* No, set defaults */
  365.    if (in->in_Node.ln_Name=strdup(AppStrings[MSG_ICONWIN_NEWNAME])) {
  366.     /* Set flags */
  367.     in->in_Flags=ICPOF_SHOWNAME;
  368.  
  369.     /* Return pointer to new node */
  370.     return(in);
  371.    }
  372.  
  373.   FreeIconNode((struct Node *) in);
  374.  }
  375.  /* Call failed */
  376.  return(NULL);
  377. }
  378.  
  379. /* Create icon node from string */
  380. struct Node *CreateIconNode(char *name)
  381. {
  382.  struct IconNode *in;
  383.  
  384.  /* Alloc memory for icon node */
  385.  if (in=AllocMem(sizeof(struct IconNode),MEMF_PUBLIC|MEMF_CLEAR)) {
  386.  
  387.   /* Init node */
  388.   if ((in->in_Node.ln_Name=strdup(name)) &&
  389.       (in->in_Exec=strdup(name)) &&
  390.       (in->in_Image=strdup(name))) {
  391.    /* Set flags */
  392.    in->in_Flags=ICPOF_SHOWNAME;
  393.  
  394.    /* All OK. */
  395.    return(in);
  396.   }
  397.  
  398.   FreeIconNode((struct Node *) in);
  399.  }
  400.  /* Call failed */
  401.  return(NULL);
  402. }
  403.  
  404. /* Activate gadget and save pointer to it */
  405. static void MyActivateGadget(ULONG num)
  406. {
  407.  ActivateGadget(gdata[num].gadget,w,NULL);
  408. }
  409.  
  410. /* Open icon edit window */
  411. BOOL OpenIconEditWindow(struct Node *node, struct Window *parent)
  412. {
  413.  /* Copy node */
  414.  if (CurrentNode=(struct IconNode *) CopyIconNode(node)) {
  415.   /* Set tags */
  416.   nametags[0].ti_Data=(ULONG) CurrentNode->in_Node.ln_Name;
  417.   exectags[0].ti_Data=(ULONG) CurrentNode->in_Exec;
  418.   imagetags[0].ti_Data=(ULONG) CurrentNode->in_Image;
  419.   soundtags[0].ti_Data=(ULONG) CurrentNode->in_Sound;
  420.   xpostags[0].ti_Data=CurrentNode->in_XPos;
  421.   ypostags[0].ti_Data=CurrentNode->in_YPos;
  422.   showntags[0].ti_Data=(CurrentNode->in_Flags & ICPOF_SHOWNAME)!=0;
  423.  
  424.   /* Create gadgets */
  425.   if (gl=CreateGadgetList(gdata,GADGETS)) {
  426.    /* Open window */
  427.    if (w=OpenWindowTags(NULL,WA_Left,        parent->LeftEdge,
  428.                              WA_Top,         parent->TopEdge+WindowTop,
  429.                              WA_InnerWidth,  ww,
  430.                              WA_InnerHeight, wh,
  431.                              WA_AutoAdjust,  TRUE,
  432.                              WA_Title,       AppStrings[MSG_ICONWIN_TITLE],
  433.                              WA_PubScreen,   PublicScreen,
  434.                              WA_Flags,       WFLG_CLOSEGADGET|WFLG_DRAGBAR|
  435.                                              WFLG_DEPTHGADGET|WFLG_RMBTRAP|
  436.                                              WFLG_ACTIVATE,
  437.                              TAG_DONE)) {
  438.     /* Add gadgets to window */
  439.     AddGList(w,gl,(UWORD) -1,(UWORD) -1,NULL);
  440.     RefreshGList(gl,w,NULL,(UWORD) -1);
  441.     GT_RefreshWindow(w,NULL);
  442.  
  443.     /* Activate name string gadget */
  444.     MyActivateGadget(GAD_NAME_STR);
  445.  
  446.     /* Set local variables */
  447.     w->UserPort=IDCMPPort;
  448.     w->UserData=(BYTE *) HandleIconEditWindowIDCMP;
  449.     ModifyIDCMP(w,WINDOW_IDCMP);
  450.     CurrentWindow=w;
  451.     ReqOpen=FALSE;
  452.  
  453.     /* All OK. */
  454.     return(TRUE);
  455.    }
  456.    FreeGadgets(gl);
  457.   }
  458.   FreeIconNode((struct Node *) CurrentNode);
  459.  }
  460.  /* Call failed */
  461.  return(FALSE);
  462. }
  463.  
  464. /* Close icon edit window */
  465. static void CloseIconEditWindow(void)
  466. {
  467.  /* Free resources */
  468.  if (MoveWindowPtr) CloseMoveWindow();
  469.  RemoveGList(w,gl,(UWORD) -1);
  470.  CloseWindowSafely(w);
  471.  FreeGadgets(gl);
  472. }
  473.  
  474. /* If move window open, move it to new position */
  475. static void MoveMoveWindow(void)
  476. {
  477.  /* Move window open? */
  478.  if (MoveWindowPtr) {
  479.   ULONG x,y;
  480.  
  481.   /* Read current position */
  482.   x=((struct StringInfo *) gdata[GAD_XPOS_INT].gadget->SpecialInfo)->LongInt;
  483.   y=((struct StringInfo *) gdata[GAD_YPOS_INT].gadget->SpecialInfo)->LongInt;
  484.  
  485.   /* Move move window */
  486.   MoveWindow(MoveWindowPtr,x-MoveWindowPtr->LeftEdge+WBXOffset,
  487.                            y-MoveWindowPtr->TopEdge+WBYOffset);
  488.  }
  489. }
  490.  
  491. /* Exec, Image & Sound button gadget function */
  492. static void TextButtonGadgetFunc(ULONG gadnum, ULONG listnum)
  493. {
  494.  if (!ReqOpen) {
  495.   /* Save gadget number */
  496.   CurrentGadgetNum=gadnum;
  497.  
  498.   /* Open list requester */
  499.   if (OpenListRequester(listnum,w)) {
  500.    /* Disable window */
  501.    DisableWindow(w,&DummyReq);
  502.  
  503.    /* Set update function */
  504.    UpdateWindow=UpdateIconEditWindow;
  505.    ReqOpen=TRUE;
  506.   }
  507.  }
  508. }
  509.  
  510. /* OK gadget function */
  511. static struct Node *OKGadgetFunc(void)
  512. {
  513.  struct Node *rc;
  514.  char *s;
  515.  
  516.  /* Free old string */
  517.  if (s=CurrentNode->in_Node.ln_Name) free(s);
  518.  
  519.  /* Duplicate new string */
  520.  if ((CurrentNode->in_Node.ln_Name=
  521.        DuplicateBuffer(gdata[GAD_NAME_STR].gadget)) != (char *) -1) {
  522.   /* Copy integer gadget values */
  523.   CurrentNode->in_XPos=
  524.    ((struct StringInfo *) gdata[GAD_XPOS_INT].gadget->SpecialInfo)->LongInt;
  525.   CurrentNode->in_YPos=
  526.    ((struct StringInfo *) gdata[GAD_YPOS_INT].gadget->SpecialInfo)->LongInt;
  527.  
  528.   rc=(struct Node *) CurrentNode;
  529.  } else {
  530.   /* Couldn't copy strings */
  531.   rc=(struct Node *) -1;
  532.   FreeIconNode((struct Node *) CurrentNode);
  533.  }
  534.  return(rc);
  535. }
  536.  
  537. /* Handle icon edit window IDCMP events */
  538. void *HandleIconEditWindowIDCMP(struct IntuiMessage *msg)
  539. {
  540.  struct Node *NewNode=NULL;
  541.  
  542.  /* Which IDCMP class? */
  543.  switch (msg->Class) {
  544.   case IDCMP_CLOSEWINDOW:   NewNode=(struct Node *) -1;
  545.                             FreeIconNode((struct Node *) CurrentNode);
  546.                             break;
  547.   case IDCMP_REFRESHWINDOW: GT_BeginRefresh(w);
  548.                             GT_EndRefresh(w,TRUE);
  549.                             break;
  550.   case IDCMP_GADGETUP:
  551.    switch (((struct Gadget *) msg->IAddress)->GadgetID) {
  552.     case GAD_EXEC_BUT:  TextButtonGadgetFunc(GAD_EXEC_TXT,LISTREQ_EXEC);
  553.                         break;
  554.     case GAD_IMAGE_BUT: TextButtonGadgetFunc(GAD_IMAGE_TXT,LISTREQ_IMAGE);
  555.                         break;
  556.     case GAD_SOUND_BUT: TextButtonGadgetFunc(GAD_SOUND_TXT,LISTREQ_SOUND);
  557.                         break;
  558.     case GAD_XPOS_INT:  MoveMoveWindow();
  559.                         break;
  560.     case GAD_YPOS_INT:  MoveMoveWindow();
  561.                         break;
  562.     case GAD_POSITION:  /* Move window open? */
  563.                         if (MoveWindowPtr)
  564.                          /* Yes. Close move window */
  565.                          CloseMoveWindow();
  566.                         else {
  567.                          /* No. Open it! */
  568.                          MoveWindowOffX=WBXOffset;
  569.                          MoveWindowOffY=WBYOffset;
  570.  
  571.                          /* Open move window */
  572.                          OpenMoveWindow(w,gdata[GAD_XPOS_INT].gadget,
  573.                                           gdata[GAD_YPOS_INT].gadget);
  574.                         }
  575.                         break;
  576.     case GAD_SHOWNAME:  /* Toggle flag */
  577.                         CurrentNode->in_Flags^=ICPOF_SHOWNAME;
  578.                         break;
  579.     case GAD_OK:        NewNode=OKGadgetFunc();
  580.                         break;
  581.     case GAD_CANCEL:    NewNode=(struct Node *) -1;
  582.                         FreeIconNode((struct Node *) CurrentNode);
  583.                         break;
  584.    }
  585.    break;
  586.   case IDCMP_VANILLAKEY:
  587.    switch (MatchVanillaKey(msg->Code,KeyArray)) {
  588.     case KEY_NAME:   MyActivateGadget(GAD_NAME_STR);
  589.                      break;
  590.     case KEY_EXEC:   TextButtonGadgetFunc(GAD_EXEC_TXT,LISTREQ_EXEC);
  591.                      break;
  592.     case KEY_IMAGE:  TextButtonGadgetFunc(GAD_IMAGE_TXT,LISTREQ_IMAGE);
  593.                      break;
  594.     case KEY_SOUND:  TextButtonGadgetFunc(GAD_SOUND_TXT,LISTREQ_SOUND);
  595.                      break;
  596.     case KEY_XPOS:   MyActivateGadget(GAD_XPOS_INT);
  597.                      break;
  598.     case KEY_YPOS:   MyActivateGadget(GAD_YPOS_INT);
  599.                      break;
  600.     case KEY_SHOW:   /* Toggle flag */
  601.                      CurrentNode->in_Flags^=ICPOF_SHOWNAME;
  602.  
  603.                      /* Set check box gadget */
  604.                      GT_SetGadgetAttrs(gdata[GAD_SHOWNAME].gadget,w,NULL,
  605.                       GTCB_Checked, (CurrentNode->in_Flags & ICPOF_SHOWNAME),
  606.                       TAG_DONE);
  607.  
  608.                      break;
  609.     case KEY_OK:     NewNode=OKGadgetFunc();
  610.                      break;
  611.     case KEY_CANCEL: NewNode=(struct Node *) -1;
  612.                      FreeIconNode((struct Node *) CurrentNode);
  613.                      break;
  614.    }
  615.    break;
  616.  }
  617.  
  618.  /* Close window? */
  619.  if (NewNode) {
  620.   /* Yes. But first reply message!!! */
  621.   GT_ReplyIMsg(msg);
  622.   CloseIconEditWindow();
  623.  }
  624.  
  625.  return(NewNode);
  626. }
  627.  
  628. /* Update Icon edit window */
  629. void UpdateIconEditWindow(void *data)
  630. {
  631.  /* Got data? */
  632.  if (data != LREQRET_CANCEL) {
  633.   char *new;
  634.  
  635.   /* Selected something? */
  636.   new=(data == LREQRET_NOSELECT) ? NULL : ((struct Node *) data)->ln_Name;
  637.  
  638.   /* Duplicate name */
  639.   if (!new || (new=strdup(new))) {
  640.    char *old;
  641.  
  642.    /* Which object? */
  643.    switch (CurrentGadgetNum) {
  644.     case GAD_EXEC_TXT:  /* Set new Exec name */
  645.                         old=CurrentNode->in_Exec;
  646.                         CurrentNode->in_Exec=new;
  647.                         break;
  648.     case GAD_IMAGE_TXT: /* Set new Image name */
  649.                         old=CurrentNode->in_Image;
  650.                         CurrentNode->in_Image=new;
  651.                         break;
  652.     case GAD_SOUND_TXT: /* Set new Sound name */
  653.                         old=CurrentNode->in_Sound;
  654.                         CurrentNode->in_Sound=new;
  655.                         break;
  656.    }
  657.  
  658.    /* Free old string */
  659.    if (old) free(old);
  660.  
  661.    /* Set new text */
  662.    GT_SetGadgetAttrs(gdata[CurrentGadgetNum].gadget,w,NULL,GTTX_Text,new,
  663.                                                            TAG_DONE);
  664.   }
  665.  }
  666.  
  667.  /* Enable window */
  668.  EnableWindow(w,&DummyReq,WINDOW_IDCMP);
  669.  
  670.  /* Restore update function pointer */
  671.  UpdateWindow=UpdateMainWindow;
  672.  CurrentWindow=w;
  673.  ReqOpen=FALSE;
  674. }
  675.  
  676. /* Read TMIC IFF chunk into Icon node */
  677. struct Node *ReadIconNode(UBYTE *buf)
  678. {
  679.  struct IconNode *in;
  680.  
  681.  /* Allocate memory for node */
  682.  if (in=AllocMem(sizeof(struct IconNode),MEMF_PUBLIC|MEMF_CLEAR)) {
  683.   struct IconPrefsObject *ipo=(struct IconPrefsObject *) buf;
  684.   ULONG sbits=ipo->ipo_StringBits;
  685.   UBYTE *ptr=(UBYTE *) &ipo[1];
  686.  
  687.   if ((!(sbits & ICPO_NAME) || (in->in_Node.ln_Name=GetConfigStr(&ptr))) &&
  688.       (!(sbits & ICPO_EXEC) || (in->in_Exec=GetConfigStr(&ptr))) &&
  689.       (!(sbits & ICPO_IMAGE) || (in->in_Image=GetConfigStr(&ptr))) &&
  690.       (!(sbits & ICPO_SOUND) || (in->in_Sound=GetConfigStr(&ptr)))) {
  691.    /* Copy flags & values */
  692.    in->in_Flags=ipo->ipo_Flags;
  693.    in->in_XPos=ipo->ipo_XPos;
  694.    in->in_YPos=ipo->ipo_YPos;
  695.  
  696.    /* All OK. */
  697.    return(in);
  698.   }
  699.  
  700.   /* Call failed */
  701.   FreeIconNode((struct Node *) in);
  702.  }
  703.  return(NULL);
  704. }
  705.  
  706. /* Write Icon node to TMIC IFF chunk */
  707. BOOL WriteIconNode(struct IFFHandle *iff, UBYTE *buf, struct Node *node)
  708. {
  709.  struct IconNode *in=(struct IconNode *) node;
  710.  struct IconPrefsObject *ipo=(struct IconPrefsObject *) buf;
  711.  ULONG sbits=0;
  712.  UBYTE *ptr=(UBYTE *) &ipo[1];
  713.  
  714.  /* Copy strings */
  715.  if (PutConfigStr(in->in_Node.ln_Name,&ptr)) sbits|=ICPO_NAME;
  716.  if (PutConfigStr(in->in_Exec,&ptr)) sbits|=ICPO_EXEC;
  717.  if (PutConfigStr(in->in_Image,&ptr)) sbits|=ICPO_IMAGE;
  718.  if (PutConfigStr(in->in_Sound,&ptr)) sbits|=ICPO_SOUND;
  719.  
  720.  /* set string bits */
  721.  ipo->ipo_StringBits=sbits;
  722.  
  723.  /* Copy flags & values */
  724.  ipo->ipo_Flags=in->in_Flags;
  725.  ipo->ipo_XPos=in->in_XPos;
  726.  ipo->ipo_YPos=in->in_YPos;
  727.  
  728.  /* calculate length */
  729.  sbits=ptr-buf;
  730.  
  731.  DEBUG_PRINTF("chunk size %ld\n",sbits);
  732.  
  733.  /* Open chunk */
  734.  if (PushChunk(iff,0,ID_TMIC,sbits)) return(FALSE);
  735.  
  736.  /* Write chunk */
  737.  if (WriteChunkBytes(iff,buf,sbits)!=sbits) return(FALSE);
  738.  
  739.  /* Close chunk */
  740.  if (PopChunk(iff)) return(FALSE);
  741.  
  742.  /* All OK. */
  743.  return(TRUE);
  744. }
  745.